/*
 * Copyright (c) 2018. J4dream created
 */

package com.j4dream.property.javabasic.thread;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

@Slf4j
public class ThreadVolatile {
    public volatile int inc = 0;

    public void increase() {
        inc++;
    }

    public static void main(String[] args) {
        final ThreadVolatile test = new ThreadVolatile();
        for (int i = 0; i < 10; i++) {
            new Thread() {
                public void run() {
                    for (int j = 0; j < 1000; j++) {
                        test.increase();
                        if (j==999) {
                            log.info(j + "");
                        }
                    }

                }

                ;
            }.start();
        }
        log.info(Thread.activeCount() + "");
        // Idea 默认会有两个线程启动 Main 线程，以及 Monitor Ctrl-Break 线程。
        while (Thread.activeCount() > 2) {
            Thread.yield();
        }

        // 最终结果大部分时候少于 10 * 1000;
        // 自增操作不是原子性操作，而且volatile也无法保证对变量的任何操作都是原子性的。
        log.info(test.inc + "");
        Lock lock = new ReentrantLock();

        // 解决办法
        // 1. synchronized increase 方法；
        // 2. Lock lock = new ReentrantLock(); lock.locked() inc++;
        // 3. 使用 AtomicInteger();

    }
}
